#ifndef _FNT_SESSION_H_
#define _FNT_SESSION_H_

#include <QMainWindow>

class Tracer;
class Viewer;
class Options;
struct Point;
class Edge;
struct Cube;
struct LoadThreadInput;

class QItemSelection;
class QMenu;

enum SessionAction {
	SESSION_SAVE, SESSION_SAVE_AS,
	/* misc */
	SESSION_CLOSE,

	/* edit */
	EDIT_UNDO, EDIT_REDO,
	EDIT_CHANGE_TYPE, EDIT_CHANGE_MARK, EDIT_CHANGE_SIZE,
	EDIT_IMPORT_FNT,
	EDIT_IMPORT_SWC,
	EDIT_ABORT,

	/* position */
	EDIT_GOTO_TARGET, EDIT_PICK_CURRENT, EDIT_GOTO_POS,
	EDIT_LOAD_DATA, EDIT_LOAD_DATA_AUTO,
	EDIT_CONTRAST_AUTO,

	/* neurons */
	EDIT_NEW_NEURON, EDIT_RENAME_NEURON, EDIT_DEL_NEURONS, EDIT_PURGE_NEURONS,

	/* tracing */
	TRACING_FIND, TRACING_CONNECT, TRACING_REFINE,
	TRACING_CONN_AUTO,
	TRACING_DONE, TRACING_BRANCH, TRACING_EXTEND,TRACING_CHECKED,
	TRACING_MARK1, TRACING_MARK2, TRACING_MARK3,TRACING_MARK4, TRACING_MARK_CLEAR,
	TRACING_DELETE,
	TRACING_CONNECT_SIMPLE,

	/* view */
	VIEW_SLICE,
	VIEW_EDGE,
	VIEW_CHANEL,

	DEBUG_SAVE_CUBE,
	DEBUG_SCREENSHOT,
	DEBUG_START_ROTATE,
	SESSION_ACTION_NUM
};

enum class SessionState {
	Invalid,
	LoadingCatalog,
	Readonly,
	Ready,
	Computing,
	LoadingCubes
};

struct SessionPriv;
class Session: public QMainWindow {

	Q_OBJECT;
	friend struct SessionPriv;
	SessionPriv*const priv;

	void closeEvent(QCloseEvent* event) override;

Q_SIGNALS:
	void sessionReady(Session* s, bool err);
	void requestCloseSession(Session* s);
	void stateChanged(Session* s, SessionState ss);

	private Q_SLOTS:
		void saveSession();
		void saveSessionAs();
		void readGraph();
		void closeSession();

		void undoCommand();
		void redoCommand();
		void jumpPosition();
		void jumpToTarget();
		void pickCurrent();
		void startDownloadCube();
		void toggleAutoDownload();
		void toggleAutoContrast();
		void toggleAutoConnect();
		void changeType();
		void changeMark();
		void changeSize();
		void createNeuron();
		void renameNeuron();
		void removeNeurons();
		void purgeNeurons();
		void importFnt();
		void importSwc();

		void findPath();
		void connectPoints();
		void changeConnectType();
		void refinePath();
		void finishBranch();
		void checkedBranch();
		void createBranch();
		void extendBranch();
		void setMark1();
		void setMark2();
		void setMark3();
		void setMark4();
		void clearMark();
		void removeEdge();

		void abortOperation();

		void saveCurrentCube();
		void takeScreenshot();
		void toggleRotate();



		void setPositionCur(int v);
	void setPositionTgt(int v);

	void selectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
	void currentChanged(const QModelIndex& selected, const QModelIndex& deselected);
	void labelSelectionChanged(const QItemSelection& selected, const QItemSelection& deselected);
	void labelCurrentChanged(const QModelIndex& selected, const QModelIndex& deselected);

	void computeFinished();
	void showComputeProgress();
	void computeThreadWarning(const QString& msg);
	void computeThreadError(const QString& msg);

	void loadThreadWarning(const QString& msg);
	void loadThreadError(const QString& msg);
	void sourcesReady();
	void cubeFinished();
	void updateProgress(int cur, int tot);

	void timeoutFiveMinute();


	public Q_SLOTS:
	public:

		void viewerReady(bool err);
		Session(const LoadThreadInput& input);
		Session(const QString& file);
		Session(const QString& file, const QString& swap);
		~Session();

		Options* options();

		void pickPosition(Edge e, size_t i, const Point* pos);
		void jumpToPosition(Edge e, size_t i, const Point* pos);
		void updateActions();
		void showPopupMenu(const QPoint& pt);

		bool closeSessionImp();


		void attachOptionsDlg();
		void detachOptionsDlg();

		SessionState state() const;

		//void closeEvent(QCloseEvent* ev) override;


		//void showPopupMenu(const QPoint& pt);

		//void addSession(Session* s);
		//void showStatus(const QString& m, int t);
		//bool closeWindowImp();
		//void viewerReady(bool err);

		//Session* activeSession() const;
		//Options* options(); global

		//void updateActions();

		//void closeEvent(QCloseEvent* ev) override;
};

#endif
